package com.luhuiguo.cms.server.service.impl;

import java.util.Date;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.PersistenceUnit;
import javax.persistence.Query;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.luhuiguo.cms.server.entity.Article;
import com.luhuiguo.cms.server.service.ArticleService;
import com.luhuiguo.cms.server.util.SecurityUtils;

@Service
// @Transactional
public class ArticleServiceImpl implements ArticleService {

    @PersistenceUnit
    private EntityManagerFactory emf;

    // @PersistenceContext
    // private EntityManager em;

    @Override
    public Article getArticle(Long id) {
        EntityManager em = emf.createEntityManager();
        try {
            return em.find(Article.class, id);
        } finally {
            em.close();
        }
    }

    @SuppressWarnings("unchecked")
    @Override
    public List<Article> findArticles() {
        EntityManager em = emf.createEntityManager();
        try {
            Query q = em.createQuery("SELECT t FROM Article t ORDER BY t.lastModified desc");
            List<Article> list = q.getResultList();
            list.size();
            return list;
        } finally {
            em.close();
        }
    }

    @SuppressWarnings("unchecked")
    @Override
    public List<Article> findArticlesByChannel(Long channel, int... rowStartIdxAndCount) {
        EntityManager em = emf.createEntityManager();
        try {
            Query q = em.createQuery("SELECT t FROM Article t WHERE t.channel = :channel ORDER BY t.lastModified desc");
            q.setParameter("channel", channel);

            if (rowStartIdxAndCount != null && rowStartIdxAndCount.length > 0) {
                int rowStartIdx = Math.max(0, rowStartIdxAndCount[0]);
                if (rowStartIdx > 0) {
                    q.setFirstResult(rowStartIdx);
                }
                if (rowStartIdxAndCount.length > 1) {
                    int rowCount = Math.max(0, rowStartIdxAndCount[1]);
                    if (rowCount > 0) {
                        q.setMaxResults(rowCount);
                    }
                }
            }
            List<Article> list = q.getResultList();
            list.size();

            return list;
        } finally {
            em.close();
        }
    }

    @Override
    public void saveArticle(Article article) {
        EntityManager em = emf.createEntityManager();
        try {
            article.setCreated(new Date());
            article.setCreatedBy(SecurityUtils.getCurrentUsername());
            article.setLastModified(article.getCreated());
            article.setLastModifiedBy(article.getCreatedBy());
            em.persist(article);
        } finally {
            em.close();
        }

    }

    @Override
    public Article updateArticle(Article article) {
        EntityManager em = emf.createEntityManager();
        try {
            article.setLastModified(new Date());
            article.setLastModifiedBy(SecurityUtils.getCurrentUsername());
            return em.merge(article);
        } finally {
            em.close();
        }
    }

    @Override
    public void deleteArticle(Long id) {
        EntityManager em = emf.createEntityManager();
        try {
            em.remove(em.find(Article.class, id));
        } finally {
            em.close();
        }
    }

    @Override
    public int getCountByChannel(Long channel) {
        EntityManager em = emf.createEntityManager();
        try {
            Query q = em.createQuery("SELECT COUNT(t) FROM Article t WHERE t.channel = :channel");
            q.setParameter("channel", channel);

            return (Integer) q.getSingleResult();
        } finally {
            em.close();
        }
    }

    @Override
    public void deleteArticleByChannel(Long channel) {
        List<Article> list = findArticlesByChannel(channel);
        for (Article item : list) {
            deleteArticle(item.getId());
        }
    }

}
